/*
 * Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@gmail.com>
 * Licensed to the Wang Pengcheng under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The LGPL licenses this file to You under the GNU Lesser General Public
 * Licence, Version 2.0  (the "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of the License at
 *
 *     http://www.gnu.org/licenses/lgpl.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//29 Aug 2007
package cn.edu.whu.control;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;

import cn.edu.whu.data.DataList;
import cn.edu.whu.data.VarList;
import cn.edu.whu.data.Data;

/**
 * Edit the DatabaseAction.java
 * 
 * @author wpc
 * @version 0.0.1
 * 
 */
public class EditAction {

	// The list of the template's vars
	private static String[] st = { "begin", "select all", "select one list",
			"select one object", "insert", "update", "delete one",
			"delete all", "end" };

	// Save the vars
	private VarList var;

	// Save the information about the javaBean's attributes
	private DataList list;

	// The location of the template file DataBaseAction.java
	private static String fileUrl = BasicDataForEdit.TEMPLATE_FILE_DIR+"databaseAction/DataBaseAction.java";

	// The location of the output file DataBaseAction.java
	private static String SALE_FILE_NAME = "testAction.java";

	// Save the template files strings DataBaseAction.java
	private static HashMap<String, String> mapTemp = new HashMap<String, String>();

	// Save the output files strings DataBaseAction.java
	private static HashMap<String, String> map = new HashMap<String, String>();

	/**
	 * The constructor. Set the information location and clear the strings sets.
	 * 
	 * @param var
	 *            the vars set
	 * @param list
	 *            the javaBean's information list
	 */
	public EditAction(VarList var, DataList list) {
		this.var = var;
		this.list = list;

		map.clear();
		mapTemp.clear();
	}

	/**
	 * Read the template file strings.
	 * 
	 * @throws Exception
	 *             the iostream exception
	 */
	public void read() throws Exception {

		// InputStream storageFile = getClass().getResourceAsStream(fileUrl);

		FileInputStream storageFile = new FileInputStream(fileUrl);

		BufferedReader in = new BufferedReader(new InputStreamReader(
				storageFile));

		String i = "";
		String k = "";

		while (true) {
			String s = in.readLine();
			if (s == null) {
				mapTemp.put(k, i);
				break;
			}

			if (s.contains("//<!--")) {
				if (!(k.equals(""))) {
					mapTemp.put(k, i);
				}
				i = "";
				k = s.substring(s.indexOf("//<!--") + 6);
				map.put(k, s + "\n");
			} else {
				i += s + "\n";
			}
		}
	}

	/**
	 * Add method for adding the sql sentences.
	 * 
	 * @param addString
	 *            the sentences for asking adding
	 */
	public void add(String addString) {
		if (addString.contains("init")) {
			initFile();
		} else {
			String[] s = addString.split(" ");
			if (s[0].equals("select")) {
				addSelectOne(s[2]);
			} else if (s[0].equals("delete")) {
				addDeleteOne(s[2]);
			}
		}
	}

	private void addInsert() {
		String p = st[4];
		String s = mapTemp.get(p);
		for (int c = 0; c < var.length(); c++) {
			String regex = var.getVar(c);
			String replacement = var.getValue(c);
			s = s.replace(regex, replacement);
		}
		map.put(p, map.get(p) + s);
	}

	private void addUpdate() {
		String p = st[5];
		String s = mapTemp.get(p);
		for (int c = 0; c < var.length(); c++) {
			String regex = var.getVar(c);
			String replacement = var.getValue(c);
			s = s.replace(regex, replacement);
		}
		map.put(p, map.get(p) + s);
	}

	private void addSelectOne(String name) {
		Data d = list.getByName(name);

		String p = null;

		try {
			if (d.isOnly()) {
				p = st[3];
			} else {
				p = st[2];
			}
		} catch (NullPointerException e) {
			e.printStackTrace();
			System.out.println();
			System.err.println("The var is not in the Bean: " + name);
			System.exit(1);

		}

		String s = mapTemp.get(p);
		var.setValue("$TYPE", (d).getType());
		var.setValue("$NAME", (d).getName());
		var.setValue("$METHODNAME", (d).getMethodName());
		for (int c = 0; c < var.length(); c++) {
			String regex = var.getVar(c);
			String replacement = var.getValue(c);
			s = s.replace(regex, replacement);
		}
		map.put(p, map.get(p) + s);
	}

	public void addSelectAll() {
		String p = st[1];
		String s = mapTemp.get(p);
		for (int c = 0; c < var.length(); c++) {
			String regex = var.getVar(c);
			String replacement = var.getValue(c);
			s = s.replace(regex, replacement);
		}
		map.put(p, map.get(p) + s);
	}

	public void addDeleteOne(String name) {
		Data d = list.getByName(name);

		String p = st[6];

		String s = mapTemp.get(p);
		var.setValue("$TYPE", (d).getType());
		var.setValue("$NAME", (d).getName());
		var.setValue("$METHODNAME", (d).getMethodName());
		for (int c = 0; c < var.length(); c++) {
			String regex = var.getVar(c);
			String replacement = var.getValue(c);
			s = s.replace(regex, replacement);
		}
		map.put(p, map.get(p) + s);
	}

	public void addDeleteAll() {
		String p = st[7];
		String s = mapTemp.get(p);
		for (int c = 0; c < var.length(); c++) {
			String regex = var.getVar(c);
			String replacement = var.getValue(c);
			s = s.replace(regex, replacement);
		}
		map.put(p, map.get(p) + s);
	}

	private void editBeginEnd() {
		String[] st = { "begin", "end" };
		for (int p = 0; p < st.length; p++) {
			String s = mapTemp.get(st[p]);
			for (int i = 0; i < var.length(); i++) {
				String regex = var.getVar(i);
				String replacement = var.getValue(i);
				s = s.replace(regex, replacement);
			}
			map.put(st[p], map.get(st[p]) + s);
		}
	}

	public void read(String url) throws Exception {
		fileUrl = url;
		read();
	}

	public void initFile() {
		editBeginEnd();
		addInsert();
		addUpdate();
		addSelectAll();
		addDeleteAll();

		addDeleteOne((list.get(0)).getName());
		addSelectOne((list.get(0)).getName());
	}

	public void write() throws Exception {
		FileOutputStream saleFile = new FileOutputStream(SALE_FILE_NAME);
		BufferedWriter out = new BufferedWriter(
				new OutputStreamWriter(saleFile));
		out.flush();
		out.newLine();
		for (int i = 0; i < st.length; i++) {
			out.append(map.get(st[i]));
		}
		out.close();
	}

	public void setPath(String url) {
		SALE_FILE_NAME = url;
	}

}
